//
//  HD_HSP_Location.m
//  HDLianXuDingWeiDemo
//
//  Created by HDHaoShaoPeng on 2017/5/22.
//  Copyright © 2017年 HDHaoShaoPeng. All rights reserved.
//

#import "HD_HSP_Location.h"
#import "GCDAsyncUdpSocket.h"
#import "XMLDictionary.h"
#import <CoreLocation/CoreLocation.h>

@interface HD_HSP_Location ()<GCDAsyncUdpSocketDelegate> {
    GCDAsyncUdpSocket *udpSocket;
    NSMutableArray *pareArray;
}

@property (nonatomic, strong) NSTimer *myTimer;
@end


@implementation HD_HSP_Location
{
    NSString *_uploadString;
    NSString *_requestString;
    
    NSString *_serverIP;
    NSString *_serverAdress;
    NSString *_soapActionAdress;
    int16_t _portAdress;
}

#pragma mark - -------- 初始化方法 ---------

-(instancetype)initWithServerIP:(NSString *)serverIP andServerAdress:(NSString *)serverAdress andSoapActionAdress:(NSString*)soapActionAdress anduploadPort:(int)port
{
    self = [super init];
    if (self)
    {
        _serverIP = serverIP;
        _serverAdress = serverAdress;
        _soapActionAdress = soapActionAdress;
        _portAdress = port;
        
        [self bindPort];//绑定服务器 初始化udpSocket
        
        self.myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(requestStepMapID:) userInfo:nil repeats:YES];//定时获取当前位置信息。
    }
    
    return self;
}

- (id)init
{
    self = [super init];
    if (self)
    {
        [self bindPort];//绑定服务器 初始化udpSocket
        
        self.myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(requestStepMapID:) userInfo:nil repeats:YES];//定时获取当前位置信息。
    }
    
    return self;
}

- (void)bindPort
{
    udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    
    NSError *error = nil;
    if (![udpSocket bindToPort:_portAdress error:&error])
    {
        NSLog(@"Error binding: %@", error);
        return;
    }
    
    if (![udpSocket beginReceiving:&error])
    {
        NSLog(@"Error receiving: %@", error);
        return;
    }
}

-(void)releaseMethod
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [udpSocket close];
    udpSocket.delegate = nil;
    udpSocket = nil;
    [self cleanTimer];
}

- (void)cleanTimer
{
    [self.myTimer invalidate];
    self.myTimer = nil;
}


#pragma mark - ------------- udpSocket Delegate ---------------

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didConnectToAddress:(NSData *)address
{
    LOG(@"Now Udp is connected!!!......");
}


- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotConnect:(NSError * _Nullable)error
{
    LOG(@"链接失败：%@",error);
}

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag{
    LOG(@"发送成功：%ld",tag);
}

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError * _Nullable)error
{
    LOG(@"发送失败：%@",error);
}

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
      fromAddress:(NSData *)address
withFilterContext:(nullable id)filterContext
{
}

- (void)udpSocketDidClose:(GCDAsyncUdpSocket *)sock withError:(NSError  * _Nullable)error
{
    LOG(@"关闭了。。。");
}

#pragma mark - ------------------- 私有方法 -----------------------

#pragma mark 反馈蓝牙卡片的信息

-(void)feedbackiBeaconMessagesWith:(NSArray *)ibeacons
{
    NSMutableString *ibeaconsString = [[NSMutableString alloc]initWithCapacity:300];
    
    for (CLBeacon *bea in ibeacons) {
        NSString *mess = [NSString stringWithFormat:@"Minor:%d --- Rssi:%ld \n",bea.minor.intValue,(long)bea.rssi];
        [ibeaconsString appendString:mess];
    }
    
    NSString *backStr = ibeaconsString;
    [self.myDelegate feedbackiBeaconMessagesWith:backStr];
}

#pragma mark 发送消息到服务器

- (void)udpParameterWith:(NSNotification *)noti
{
    NSArray *beaconArray = noti.object;
    if (beaconArray.count == 0)
    {
        return;
    }
    else
    {
        LOG(@"*************/n")
        for (CLBeacon *bea in beaconArray) {
            LOG(@"上传的iBeacons:%d",[bea.minor intValue]);
        }
        LOG(@"*************/n")
    }
    
    [self feedbackiBeaconMessagesWith:beaconArray];
    
    NSMutableArray *infoArray = [[NSMutableArray alloc] initWithCapacity:beaconArray.count];
    pareArray = infoArray;
    for (NSInteger i=0;i<beaconArray.count;i++)
    {
        CLBeacon *beacon = beaconArray[i];
        NSString *minorStr = [NSString stringWithFormat:@"%@",beacon.minor];
        NSString *majorStr = [NSString stringWithFormat:@"%@",beacon.major];
        NSString *hexMajor = [self hexStringFrom:majorStr];
        NSString *hexMinor = [self hexStringFrom:minorStr];
        
        NSDictionary *beaconDic1 = @{@"UUID":@"00B08E1A-1111-2222-3333-4444-5555-6666",
                                     @"Major":hexMajor,
                                     @"Minor":hexMinor,
                                     @"Model":@"iPhone6",  //设备型号
                                     @"Rssi":[NSNumber numberWithInteger:beacon.rssi],
                                     @"Battery":@"1"};
        [infoArray addObject:beaconDic1];
    }
    
    [self sendMessage];
}

- (void)sendMessage
{
    NSString *str = [self sendStr];
    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
    [udpSocket sendData:data toHost:_serverIP port:_portAdress withTimeout:-1 tag:100];
}

- (NSString *)sendStr
{
    NSString *dateStr = [self stringFromDate:[NSDate date]];
    if (self.macAdress == nil || pareArray == nil)
    {
        return nil;
    }
    
    NSDictionary *sendDic = @{@"HWType":@"iPhone",
                              @"HWId":self.macAdress,
                              @"Version":@"1.3",
                              @"Vendor":@"Apple",
                              @"Message":@"RSSI",
                              @"ScanTime":dateStr,
                              @"IBeacon":pareArray};
    
    _uploadString = [NSString stringWithFormat:@"%@",sendDic];
    
    NSString *jsonStr = [self DataTOjsonString:sendDic];
    NSData *data = [self dictionaryToDataWith:sendDic];
    [udpSocket sendData:data toHost:_serverIP port:_portAdress withTimeout:-1 tag:100];
    
    return jsonStr;
}


#pragma mark 从服务器请求信息

- (void)requestStepMapID:(id)sender
{
    if (self.macAdress == nil)//机器号为空标识
    {
        [self.myDelegate pleaseInputIdentifier];
        return;
    }
    
    //假如在这开始请求
    NSString *webServiceBodyStr = [NSString stringWithFormat:
                                   @"<GetTagStatus xmlns=\"http://www.uradiosys.com/\">"
                                   "<tagMac>%@</tagMac>"
                                   "</GetTagStatus>", self.macAdress];//这里是参数
    
    _requestString = webServiceBodyStr;
    
    NSString *webServiceStr = [NSString stringWithFormat:
                               @"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
                               "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
                               "<soap:Body>\n"
                               "%@\n"
                               "</soap:Body>\n"
                               "</soap:Envelope>", webServiceBodyStr];//webService头
    
    NSURL *url = [NSURL URLWithString:_serverAdress];
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
    NSString *msgLength = [NSString stringWithFormat:@"%ld", (unsigned long)webServiceStr.length];
    [theRequest addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-type"];
    [theRequest addValue:_soapActionAdress forHTTPHeaderField:@"SOAPAction"];
    [theRequest addValue:msgLength forHTTPHeaderField:@"Content-Length"];
    [theRequest setHTTPMethod:@"POST"];
    [theRequest setHTTPBody:[webServiceStr dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:theRequest
                                            completionHandler:
                                  ^(NSData *data, NSURLResponse *response, NSError *error) {
                                      
                                      NSString *xmlString = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding];
                                      [self handleResponseDataWith:xmlString];
                                      
                                  }];
    
    [task resume];
}


#pragma mark 处理从服务器获取到的数据

-(void)handleResponseDataWith:(NSString *)xmlString
{
    NSDictionary *xmlDoc = [NSDictionary dictionaryWithXMLString:xmlString];
    NSDictionary *bodyDic = xmlDoc[@"soap:Body"];
    NSDictionary *GetTagStatusResponseDic = bodyDic[@"GetTagStatusResponse"];
    NSDictionary *GetTagStatusResultDic = GetTagStatusResponseDic[@"GetTagStatusResult"];
    
    NSString *theX = [GetTagStatusResultDic objectForKey:@"X"];
    NSString *theY = [GetTagStatusResultDic objectForKey:@"Y"];
    
    [self.myDelegate updatePositionintWith:CGPointMake([theX floatValue], [theY floatValue])];
    NSString *showString = [NSString stringWithFormat:@"上传的参数:\n %@ \n 获取的参数: \n %@ \n 获取的数据：\n %@",_uploadString,_requestString,GetTagStatusResultDic];
    [self.myDelegate updateInfoMessagesWith:showString];
    LOG(@"收到的定位信息:%@ ----- %@",theX,theY)
}


#pragma mark - 数据格式互相转换
-(NSString*)DataTOjsonString:(id)object
{
    NSString *jsonString = nil;
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object
                                                       options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
                                                         error:&error];
    if (! jsonData) {
        NSLog(@"Got an error: %@", error);
    } else {
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    return jsonString;
}


-(NSData*)dictionaryToDataWith:(NSDictionary*)dic
{
    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:dic forKey:@"Some Key Value"];
    [archiver finishEncoding];
    return data;
}

#pragma mark 获取当前时间

- (NSString *)stringFromDate:(NSDate *)date{
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    //zzz表示时区，zzz可以删除，这样返回的日期字符将不包含时区信息。
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss zzz"];
    NSString *destDateString = [dateFormatter stringFromDate:date];
    return destDateString;
}

- (NSDate *)dateFromString:(NSString *)dateString{
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat: @"yyyy-MM-dd HH:mm:ss"];
    NSDate *destDate= [dateFormatter dateFromString:dateString];
    
    return destDate;
}

- (NSString *)hexStringFrom:(NSString *)beaconStr
{
    NSString *hexStr = nil;
    NSString *hexString = [NSString stringWithFormat:@"%@",[[NSString alloc] initWithFormat:@"%1lx",(long)beaconStr.integerValue]];
    if (hexString.length == 1)
    { hexStr = [NSString stringWithFormat:@"00:0%@",hexString]; }
    else if (hexString.length == 2)
    { hexStr = [NSString stringWithFormat:@"00:%@",hexString]; }
    else if (hexString.length == 3)
    { hexStr = [NSString stringWithFormat:@"0%@:%@",[hexString substringToIndex:1],[hexString substringWithRange:NSMakeRange(1, 2)]]; }
    else if (hexString.length == 4)
    { hexStr = [NSString stringWithFormat:@"%@:%@",[hexString substringToIndex:2],[hexString substringWithRange:NSMakeRange(2, 2)]]; }
    
    return hexStr;
}

@end
